home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / zoo21src.zoo / comment.c < prev    next >
C/C++ Source or Header  |  1991-07-24  |  10KB  |  312 lines

  1. #ifndef LINT
  2. static char sccsid[]="@(#) comment.c 2.14 88/01/24 12:42:13";
  3. #endif /* LINT */
  4.  
  5. /*
  6. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  7. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  8. */
  9.  
  10. #include "options.h"
  11. #include "portable.h"
  12. /* comment() */
  13. /* Updates comments */
  14.  
  15. /* buffer size for any one comment line */
  16. #define  COMMENT_LINE_SIZE 76
  17.  
  18. #define  MAX_COMMENT_SIZE  32767
  19. #include "zoo.h"
  20. #include "zooio.h"
  21. #include "various.h"
  22.  
  23. #ifndef NOSIGNAL
  24. #include <signal.h>
  25. #endif
  26.  
  27. #include "zoofns.h"
  28. #include "errors.i"
  29.  
  30. void show_comment PARMS ((struct direntry *, ZOOFILE, int, char *));
  31. void get_comment PARMS ((struct direntry *, ZOOFILE, char *));
  32. int needed PARMS ((char *, struct direntry *, struct zoo_header *));
  33.  
  34. void comment(zoo_path, option)
  35. char *zoo_path, *option;
  36. {
  37. #ifndef NOSIGNAL  
  38. T_SIGNAL (*oldsignal)();
  39. #endif
  40. ZOOFILE zoo_file;                         /* stream for open archive */
  41. long next_ptr;                            /* pointers to within archive */
  42. long this_dir_offset;                     /* pointers to within archive */
  43. struct direntry direntry;                 /* directory entry */
  44. struct zoo_header zoo_header;
  45. int matched = 0;                          /* any files matched? */
  46. unsigned int zoo_date, zoo_time;          /* for restoring archive timestamp */
  47. char whichname[PATHSIZE];                 /* which name to use */
  48. #ifdef ZOOCOMMENT
  49. int acmt = 0;                                        /* if changing archive comment */
  50. #endif
  51.  
  52. /* on entry option points to first letter */
  53. option++;                                            /* skip 'c' */
  54. #ifdef ZOOCOMMENT
  55. while (*option != '\0') {
  56.     if (*option == 'A') {
  57.         acmt++;                                        /* changing archive comment */
  58.         option++;
  59.     } else
  60.        prterror ('f', inv_option, *option);
  61. }
  62. #else
  63. if (*option != '\0')
  64.     prterror ('f', inv_option, *option);
  65. #endif /* ZOOCOMMENT */
  66.  
  67. if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE)
  68.    prterror ('f', could_not_open, zoo_path);
  69.  
  70. /* save archive timestamp */
  71. #ifdef GETUTIME
  72. getutime (zoo_path, &zoo_date, &zoo_time);
  73. #else
  74. gettime (zoo_file, &zoo_date, &zoo_time);
  75. #endif
  76.  
  77. /* read header and rewrite with updated version numbers, but ask user to pack
  78. archive first if archive comment is to be added and header type is 0 */
  79. #ifdef ZOOCOMMENT
  80. if (acmt)
  81.     rwheader (&zoo_header, zoo_file, 0);
  82. else
  83.     rwheader (&zoo_header, zoo_file, 1);
  84. #else
  85. rwheader (&zoo_header, zoo_file, 1);
  86. #endif
  87.  
  88. #ifdef ZOOCOMMENT
  89. /* if archive comment being added, handle it and return */
  90. if (acmt) {
  91.     void do_acmt PARMS ((struct zoo_header *, ZOOFILE, char *));
  92.     do_acmt (&zoo_header, zoo_file, zoo_path);
  93. #ifdef NIXTIME
  94.     zooclose (zoo_file);
  95.     setutime (zoo_path, zoo_date, zoo_time);    /* restore timestamp */
  96. #else
  97.     settime (zoo_file, zoo_date, zoo_time);    /* restore timestamp */
  98.     zooclose (zoo_file);
  99. #endif
  100.     return;
  101. }
  102. #endif /* ZOOCOMMENT */
  103.  
  104. /* Loop through and add comments for matching files */
  105. while (1) {
  106.    this_dir_offset = zootell (zoo_file);  /* save pos'n of this dir entry */
  107. #ifndef GLOB
  108.    readdir (&direntry, zoo_file, 1);      /* read directory entry */
  109. #else
  110.    zreaddir (&direntry, zoo_file, 1);      /* read directory entry */
  111. #endif /* GLOB */
  112.    next_ptr = direntry.next;              /* ptr to next dir entry */
  113.  
  114.    /* exit on end of directory chain or end of file */
  115.    if (next_ptr == 0L || feof(stdin))
  116.       break;
  117.  
  118.     strcpy (whichname, fullpath (&direntry));        /* full pathname */
  119.     add_version (whichname, &direntry);                /* add version suffix */
  120.    /* add comments for matching non-deleted files */
  121.    if (!direntry.deleted && needed (whichname, &direntry, &zoo_header)) {
  122.       matched++;
  123.       show_comment (&direntry, zoo_file, 1, whichname);
  124.       get_comment (&direntry, zoo_file, whichname);
  125.       zooseek (zoo_file, this_dir_offset, 0);
  126. #ifndef NOSIGNAL
  127.       oldsignal = signal (SIGINT, SIG_IGN);
  128. #endif
  129.       fwr_dir (&direntry, zoo_file);
  130. #ifndef NOSIGNAL
  131.       signal (SIGINT, oldsignal);
  132. #endif
  133.    }
  134.    zooseek (zoo_file, next_ptr, 0);   /* ..seek to next dir entry */
  135. } /* end while */
  136.  
  137. #ifdef NIXTIME
  138. zooclose (zoo_file);
  139. setutime (zoo_path, zoo_date, zoo_time);    /* restore timestamp */
  140. #else
  141. settime (zoo_file, zoo_date, zoo_time);    /* restore timestamp */
  142. zooclose (zoo_file);
  143. #endif
  144.  
  145. if (!matched)
  146.    printf ("Zoo:  %s", no_match);
  147. } /* comment */
  148.  
  149. /* show_comment() */
  150. /* shows comment on screen.  If show=1, says "Current comment is..." */
  151.  
  152. void show_comment (direntry, zoo_file, show, name)
  153. struct direntry *direntry;
  154. ZOOFILE zoo_file;
  155. int show;
  156. char *name;       /* name of file for which comment is being added */
  157. {
  158.    if (direntry->cmt_size != 0) {
  159.       unsigned int i;
  160.       char ch;
  161.       int newline = 1;
  162.       zooseek (zoo_file, direntry->comment, 0);   
  163.       if (show)
  164.          printf ("Current comment for %s is:\n", name);
  165.       for (i = 0; i < direntry->cmt_size; i++) {/* show it */
  166.          ch = zgetc (zoo_file) & 0x7f;          /* 7 bits only */
  167.          if (newline)
  168.             printf (" |");    /* indent and mark comment lines thus */
  169.          zputchar (ch);
  170.          if (ch == '\n')
  171.             newline = 1;
  172.          else
  173.             newline = 0;
  174.       }
  175.       if (!newline)              /* always terminate with newline */
  176.          zputchar ('\n');
  177.    }
  178. } /* show_comment() */
  179.  
  180.  
  181. /* get_comment() */
  182. /* Shows user old comment and updates it */
  183.  
  184. /* INPUT:
  185.    direntry points to current directory entry.
  186.    zoo_file is archive file.
  187.    this_path is full pathname of file being updated/added.
  188.  
  189.    OUTPUT:
  190.    Comment is added to file and supplied directory entry is updated
  191.    with comment size and seek position but directory entry is
  192.    not written to file.  Exceptions:  If RETURN is hit as first line,
  193.    previous comment is left unchanged.  If /END is hit, previous
  194.    comment is superseded, even if new comment is null.
  195. */
  196.  
  197. char cmt_prompt[]="[Enter %scomment for %s then type /END]\n";
  198.  
  199. void get_comment (direntry, zoo_file, this_path)  /* update comment */
  200. register struct direntry *direntry;
  201. ZOOFILE zoo_file;
  202. char *this_path;
  203. {
  204.    unsigned int line_count = 0;        /* count of new comment lines */
  205.  
  206.    zooseek (zoo_file, 0L, 2);            /* ready to append new comment */
  207. #if 0
  208.    fprintf (stderr, "[Enter comment for %s then type /END]\n", this_path);
  209. #else
  210.    fprintf (stderr, cmt_prompt, "", this_path);
  211. #endif
  212.    while (1) {
  213.       char cmt_line[COMMENT_LINE_SIZE];
  214.       int cmt_size;
  215.       if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
  216.          break;
  217.       line_count++;
  218.       if (line_count == 1) {                 /* first line typed */
  219.          if (!strcmp (cmt_line, "\n"))   /* exit if first line blank */
  220.             break;
  221.          direntry->comment = zootell (zoo_file);
  222.          direntry->cmt_size = 0;
  223.       }
  224.       if (!str_icmp (cmt_line, "/end\n"))
  225.          break;
  226.       cmt_size = strlen (cmt_line);
  227.       if (MAX_COMMENT_SIZE - direntry->cmt_size > cmt_size) {
  228.          direntry->cmt_size += (unsigned int) cmt_size;
  229.          if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
  230.             prterror ('f', disk_full);
  231.       }
  232.    } /* end while */
  233. } /* get_comment() */
  234.  
  235. #ifdef ZOOCOMMENT
  236. /*
  237. do_acmt() updates archive comment by showing it to user and 
  238. requesting a new one.  Typed input terminates as with file comment,
  239. i.e., empty initial line leaves comment unchanged, case-insensitive
  240. "/end" terminates input comment.
  241. */
  242. void do_acmt (zoo_header, zoo_file, zoo_path)
  243. struct zoo_header *zoo_header;
  244. ZOOFILE zoo_file;
  245. char *zoo_path;
  246. {
  247.    unsigned int line_count = 0;        /* count of new comment lines */
  248.     void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
  249.  
  250.     show_acmt (zoo_header, zoo_file, 1);    /* show current archive comment */
  251.    zooseek (zoo_file, 0L, 2);            /* ready to append new comment */
  252. #if 0
  253.    fprintf (stderr, "[Enter archive comment for %s then type /END]\n", 
  254.                             zoo_path);
  255. #else
  256.    fprintf (stderr, cmt_prompt, "archive ", zoo_path);
  257. #endif
  258.  
  259.    while (1) {
  260.       char cmt_line[COMMENT_LINE_SIZE];
  261.       int cmt_siz